#!/bin/bash
#
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Copies all logs, screen-shots, crash dumps to Downloads folder.
# Help information about script usage.

. /usr/share/misc/shflags

DEFINE_boolean screenshots $FLAGS_FALSE \
    "To also collect saved screenshots"
DEFINE_boolean profile_data $FLAGS_FALSE \
    "To also collect profile web data and sync data"
DEFINE_boolean delete_autotest_data $FLAGS_FALSE \
    "Delete autotest results after copying if they exist"
FLAGS_HELP="USAGE: To collect logs and crash dumps: sh $0 [flags] \
    \nCollected data is zipped to tar.gz file with timestamp in /\/tmp."

# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"

home_dir=/home/chronos
log_dir=/tmp/diagnostic_logs
tar_path=/tmp

mkdir -p ${log_dir}
sudo rm -rf ${log_dir}/*

# Copying file with current timestamp and date.
date > ${log_dir}/timestamp.txt
echo "Copied current timestamp"

# Copying file with ping test result.
ping -c 5 google.com > ${log_dir}/ping_result.txt
echo "Copied ping test result"

# Run lsusb.
sudo lsusb -v > ${log_dir}/lsusb_output.txt &&
    echo "Obtaining lsusb information"

# Run lspci
sudo lspci -v > ${log_dir}/lspci_output.txt &&
    echo "Obtaining lspci information"

# Run lspci in numeric mode
sudo lspci -vn > ${log_dir}/lspci_numeric_output.txt &&
    echo "Obtaining lspci numeric information"

# Run iw list
sudo iw list > ${log_dir}/iw_list_output.txt &&
    echo "Obtaining network interface information"

# Copying lsb-release file.
sudo cp /etc/lsb-release ${log_dir}/lsb_release.txt &&
    echo "Copied lsb-release file with version information"

# Copying Consent To Send Stats file for client id.
sudo cp "${home_dir}/Consent To Send Stats" \
    ${log_dir}/consent_to_send_stats.txt &&
    echo "Copied Consent To Send Stats file with client id"

# Copying Local State file from /home/chronos.
sudo cp "${home_dir}/Local State" ${log_dir}/local_state.txt &&
    echo "Copied Local State file"

# Get the Display output.  Prefer modetest (freon) over xrandr.
if [ -e /usr/bin/modetest ]; then
    /usr/bin/modetest > ${log_dir}/modetest_output.txt &&
        echo "Dumped modetest output"
else
    DISPLAY=:0.0 /usr/bin/xrandr --verbose > ${log_dir}/xrand_output.txt &&
        echo "Dumped xrandr output"
fi

# Get modem status
/usr/bin/modem status > ${log_dir}/modem_status.txt &&
    echo "Dumped modem status"

# Get audio diagnostics
sudo /usr/bin/audio_diagnostics > ${log_dir}/audio_diagnostics.txt &&
    echo "Dumped audio diagnostics"

# Get trackpad user feedback
sudo /opt/google/input/cmt_feedback > \
    ${log_dir}/trackpad_feedback.dat &&
    echo "Dumped touchpad feedback"

ts_exists="/opt/google/input/inputcontrol --names -t touchscreen"
if [[ -n $(${ts_exists}) ]]; then
  # Get touchscreen user feedback
  sudo /opt/google/input/evdev_feedback > \
      ${log_dir}/touchscreen_feedback.dat &&
      echo "Dumped touchscreen feedback"
fi

# Get shill's service list
sudo /usr/bin/network_diag --show-macs --flimflam > \
    ${log_dir}/shill_services_list.txt &&
    echo "Dumped shill's service list"

# Get the network diagnostics
sudo /usr/bin/network_diag > ${log_dir}/network_diagnostics.txt &&
    echo "Dumped network_diagnostics"

# Copying mount-encrypted log
sudo cp /tmp/mount-encrypted.log ${log_dir} &&
    echo "Copied mount encryption log"

# Copy the stateful partition permission map.
sudo ls -alR /mnt/stateful_partition/ > ${log_dir}/stateful.txt &&
    echo "Copied list of entire stateful contents"

# List what is in the OEM folder
sudo ls -alR /opt/oem/ > ${log_dir}/oem.txt &&
    echo "Copied list of oem folder contents"

# Copy startup_manifest.json.txt if it exists
if [ -e /opt/oem/etc/startup_manifest.json ]; then
    cp /opt/oem/etc/startup_manifest.json ${log_dir}/startup_manifest.json.txt
fi

mkdir -p ${log_dir}/system_level_logs ${log_dir}/crashdumps
# Copying all logs under /var/log/.
sudo cp -r /var/log/* ${log_dir}/system_level_logs &&
    echo "Copied all system level logs from /var/log/"

user_home_dirs=($(mount | grep -o "/home/user/[[:alnum:]]\{,\}" \
                  | sed 's:/home/user/::'))

# Iterate through all of the mounted home directories and grab the
# requested data.
for ((i=0; i<${#user_home_dirs[@]}; ++i)); do
  user_log_dir=${log_dir}/user_$i
  user_home_dir=/home/user/${user_home_dirs[$i]}
  user_root_dir=/home/root/${user_home_dirs[$1]}
  mkdir ${user_log_dir}
  mkdir ${user_log_dir}/chrome_logs
  mkdir ${user_log_dir}/system_logs
  cp -r ${user_home_dir}/log/* ${user_log_dir}/chrome_logs
  sudo cp -r ${user_root_dir}/ ${user_log_dir}/system_logs
  if [ -e ${user_home_dir}/crash ]; then
    mkdir ${user_log_dir}/crash
    sudo cp -r ${user_home_dir}/crash/* ${user_log_dir}/crash &&
        echo "Copied user crash dumps"
  fi

  # Copying screen-shots if flag --screenshots is specified.
  if [ ${FLAGS_screenshots} -eq ${FLAGS_TRUE} ]; then
    cp -f ${user_home_dir}/Downloads/screenshot* ${user_log_dir}/ &&
        echo "Copied screen-shots"
  fi

  # Copying profile data if flag --profile_data is specified.
  if [ ${FLAGS_profile_data} -eq ${FLAGS_TRUE} ]; then
    cp -f "${user_home_dir}/Web Data" "${user_log_dir}/Web Data"
    cp -rf "${user_home_dir}/Sync Data" "${user_log_dir}/Sync Data" &&
        echo "Copied profile data"
  fi
done

# Copying crash dumps.
sudo cp -rf "/var/log/chrome/Crash Reports/" ${log_dir}/crashdumps/
spool_crash="/var/spool/crash/"
if [ -e ${spool_crash} ]; then
  sudo cp -rf ${spool_crash} ${log_dir}/crashdumps/ &&
      echo "Copied system crash dumps"
fi

# Dumping TPM token contents
pkcs11-tool -p 111111 -O --module libchaps.so \
    > ${log_dir}/tpm_token_contents.txt 2>&1 && echo "Dumped TPM token contents"

# Dumping Cryptohomed/TPM ownership status
cryptohome --action=status > ${log_dir}/cryptohomed_status.txt 2>&1 &&
    echo "Dumped cryptohomed status"

# Dumping Cryptohome PKCS11 status
cryptohome --action=pkcs11_token_status \
    >> ${log_dir}/cryptohomed_status.txt 2>&1 &&
    echo "Dumped cryptohomed pkcs11 status"

# Dumping firmware log if it exists
if [ -r /sys/firmware/log ]; then
  cat /sys/firmware/log > ${log_dir}/firmware_log.txt
fi

# Dumping firmware event log
if [ -n "$(sudo mosys -t | grep -o eventlog)" ]; then
  sudo mosys -k eventlog list > ${log_dir}/firmware_event_log.txt
fi

# Copy device and user policy data.
policy_dir="${log_dir}/policy_data/"
mkdir -p ${policy_dir}
device_policy="/var/lib/whitelist/"
users_policy="/home/root/*/session_manager/policy/"
if [ -e ${device_policy} ]; then
  sudo cp -rf ${device_policy} ${policy_dir} &&
      echo "Copied device whitelist"
fi
if [ -e ${users_policy} ]; then
  sudo cp -rf ${users_policy} ${policy_dir} &&
      echo "Copied user policy"
fi

# Copying autotest results if they exist
if [ -d "/usr/local/autotest/results" ]; then
  # rsync does not exist on normal images, but the autotest directory
  # will also not be found on a normal image.
  sudo rsync -a --exclude='*/sysinfo*' "/usr/local/autotest/results" \
      "${log_dir}/autotest"
  echo "Copied autotest results"
  if [ ${FLAGS_delete_autotest_data} -eq ${FLAGS_TRUE} ]; then
    rm -rf "/usr/local/autotest/results"
  fi
fi

# If we have the synaptics touchpad driver grab those additional files
if [ -e "/opt/Synaptics/bin/syncontrol" ]; then
  mkdir -p ${log_dir}/synaptic_touchpad
  sudo rm /home/chronos/user/SynDiag*
  # We can only query syncontrol if it is running
  if [ -e "/var/run/dbus/synaptics_bus_socket" ]; then
    DISPLAY=:0 /opt/Synaptics/bin/syncontrol diag
    sudo cp /home/chronos/user/SynDiag* ${log_dir}/synaptic_touchpad
  fi
fi

# Grabbing network profiles.
echo "Copying network profiles"
network_profiles_dir="${log_dir}/network_profiles"
mkdir -p ${network_profiles_dir}
for manager in shill; do
  global_profile="/var/cache/${manager}/"
  user_profile="/var/run/${manager}/user_profiles/chronos/"
  for profile in ${global_profile} ${user_profile}; do
    test -e "${profile}" && \
      sudo cp -rf --parents "${profile}" "${network_profiles_dir}"
  done
done

# Grabbing preserved memory.
if [ -e "/dev/pstore/console-ramoops" ]; then
  echo "Copying preserved memory"
  sudo cp /dev/pstore/console-ramoops "${log_dir}/console-ramoops.txt"
fi

# Compressing the log folder with all collected files.
currentdate=$(date +%m%d%y-%H%M%S)
log_file_name=log-${currentdate}.tar.gz
sudo tar czf ${tar_path}/${log_file_name} -C $(dirname ${log_dir}) \
    $(basename ${log_dir})/
sudo rm -rf ${log_dir}/

archive_path=${tar_path}/${log_file_name}
# If only one user is logged in, copy it to the download folder
if [ ${#user_home_dirs[@]} -eq 1 ]; then
  downloads="/home/user/${user_home_dirs[0]}/Downloads"
  sudo mv ${archive_path} ${downloads}
  sudo chmod 755 ${downloads}/${log_file_name}
  echo "Log file (${log_file_name}) are available in Downloads"
else
  echo "Log files are available at ${archive_path}"
fi
echo "For all flag options, run the script with --help or -h flag."
